package dao

import (
	"context"
	"errors"
	"github.com/qiniu/qmgo"
	"github.com/sirupsen/logrus"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"monoblog/common"
	"monoblog/config"
	"monoblog/domain/model"
	"strconv"
	"sync"
)

var (
	momentRepo *MomentRepository // 单例实例存储变量
	once10     sync.Once         // 确保初始化只执行一次的同步工具
)

// 初始化 QMGO 集合（单例模式）
func NewMomentRepository() *MomentRepository {
	once10.Do(func() { // 并发安全的初始化逻辑，只会执行一次
		momentRepo = &MomentRepository{
			collection: config.GetDataBase().Collection(model.MomentCollectionName), //指定集合名称
			ctx:        context.Background(),
		}
	})
	return momentRepo // 返回唯一实例
}

type MomentRepository struct {
	collection *qmgo.Collection // QMGO 集合对象（替代原生 mongo.Collection）
	ctx        context.Context  // 上下文（用于数据库操作超时控制）
}

func (impl *MomentRepository) Add(moment *model.Moment) error {
	// 取自增ID
	id, _ := NewAutoIDSequenceDao().NextID(model.MomentCollectionName)
	moment.ID = id

	_, err := impl.collection.InsertOne(impl.ctx, moment)
	return err
}

func (impl *MomentRepository) DeleteByID(id int64) error {
	//keyId, _ := primitive.ObjectIDFromHex(id)

	// 执行删除操作
	err := impl.collection.RemoveId(impl.ctx, id)
	if errors.Is(err, mongo.ErrNoDocuments) {
		logrus.Warnf("record not found. dont delete. id: %v", id)
		return nil
	}
	return err
}

func (impl *MomentRepository) UpdateReadById(id int64, read bool) error {
	//keyId, _ := primitive.ObjectIDFromHex(id)

	// 使用$set操作符实现字段更新
	updateDoc := bson.M{"$set": bson.M{"read": read}}
	err := impl.collection.UpdateId(impl.ctx, id, updateDoc)
	return err
}

func (impl *MomentRepository) UpdateReadByUserId(userId string, read bool) error {
	//keyId, _ := primitive.ObjectIDFromHex(id)

	filter := bson.M{"receiver": userId}
	// 使用$set操作符实现字段更新
	updateDoc := bson.M{"$set": bson.M{"read": read}}
	_, err := impl.collection.UpdateAll(impl.ctx, filter, updateDoc)
	return err
}

func (impl *MomentRepository) FindByID(id int64) (*model.Moment, error) {
	//keyId, _ := primitive.ObjectIDFromHex(id)
	var moment model.Moment

	err := impl.collection.Find(impl.ctx, bson.M{"_id": id}).One(&moment)

	if errors.Is(err, mongo.ErrNoDocuments) {
		logrus.Warnf("record not found. id: %v", id)
		return nil, errors.New("找不到数据, id: " + strconv.FormatInt(id, 10))
	}
	return &moment, err
}

// FindList - 按条件查询专栏列表
func (impl *MomentRepository) FindList(query common.BaseQuery) ([]*model.Moment, int, error) {
	var moments = make([]*model.Moment, 0)

	filter := bson.M{} // 构建查询条件：空条件

	var total int
	if !query.IsZero() {
		//查询条数
		n, _ := impl.collection.Find(impl.ctx, filter).Count()
		total = int(n)
	}

	//分页查询，
	err := impl.collection.Find(impl.ctx, filter).
		Sort(query.SortField()).
		Skip(int64(query.Offset())).Limit(int64(query.Limit())).
		All(&moments)
	return moments, total, err
}

// FindListByUserId 查询用户下的专栏list
func (impl *MomentRepository) FindListByUserId(userId string, query common.BaseQuery) ([]*model.Moment, int, error) {
	var moments = make([]*model.Moment, 0)

	// 构建查询条件：根据userId查询
	filter := bson.M{"receiver": userId}

	var total int
	if !query.IsZero() {
		//查询条数
		n, _ := impl.collection.Find(impl.ctx, filter).Count()
		total = int(n)
	}

	//分页查询，
	err := impl.collection.Find(impl.ctx, filter).
		Sort("-createTime").
		Skip(int64(query.Offset())).Limit(int64(query.Limit())).
		All(&moments)
	return moments, total, err
}

func (impl *MomentRepository) ExistsByTopicTargetIdReceiver(topic model.MomentTopic, targetId string, receiver string) (bool, error) {
	if topic == "" || targetId == "" || receiver == "" {
		return false, nil
	}
	// 构建查询条件
	filter := bson.M{"topic": topic, "targetId": targetId, "receiver": receiver}

	n, err := impl.collection.Find(impl.ctx, filter).Count()
	return n > 0, err
}
